home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Programming / Complete Applications / Telecom / MT Special 3 / IBM WWIV / DLOADS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-01-14  |  31.5 KB  |  1,162 lines  |  [TEXT/ttxt]

  1. Program dloads;
  2.  
  3.                       {*****************************}
  4.                       {Copyright (c) 1986 Wayne Bell}
  5.                       {*****************************}
  6.  
  7. {$V-} {$C-}
  8. TYPE j=array[1..8] of string[14];
  9.  
  10. CONST strlen=160;
  11.       comnum=1;
  12.       maxbaud=1200;
  13.       maxusers=300;
  14.       dsaves : Integer = 0;
  15.       buffer_Max    = 5120;
  16.       comptyp:j=('IBM','APPLE','TRS-80','Z-80 CP/M','COMMODORE','ATARI',
  17.                  'DUMB TERMINAL','OTHER');
  18.  
  19. TYPE str=string[strlen];
  20.      restrictions=(rlogon,rchat,rvalidate,rbackspace,ramsg,rpostan,
  21.                    rpost,remail,rvoting,rmsg);
  22.      acrq='@'..'G';
  23.      newtyp=(rp,lt,rm);
  24.      deflts=(spcsr,onekey,wordwrap,pause);
  25.      anontyp=(no,yes,forced,dearabby);
  26.      ansttype=(postn,emailn,pana,sanm,cosysop,lcosysop);
  27.      opts=(alert,smw,nomail);
  28.      slr=record
  29.            ttime:byte;
  30.            mallowed:integer;
  31.            emails,posts:byte;
  32.            anst:set of ansttype;
  33.          end;
  34.      messages=record
  35.                 ltr:char;
  36.                 number:integer;
  37.                 ext:byte;
  38.               end;
  39.      smalrec=record
  40.                name:string[25];
  41.                number:integer;
  42.              end;
  43.      userrec=record
  44.                name:string[25];
  45.                realname:string[14];
  46.                deleted:boolean;
  47.                pw:string[8];
  48.                ph:string[12];
  49.                waiting:byte;
  50.                laston:string[10];
  51.                loggedon:integer;
  52.                msgpost:integer;
  53.                emailsent:integer;
  54.                feedback:integer;
  55.                linelen:byte;
  56.                pagelen:byte;
  57.                defaults:set of deflts;
  58.                ontoday:byte;
  59.                illegal:byte;
  60.                cursor:string[10];
  61.                sl:byte;
  62.                ac:set of restrictions;
  63.                ar:set of acrq;
  64.                qscan:array[1..19] of messages;
  65.                qscn:array[1..19] of boolean;
  66.                macro:array[1..2] of string[79];
  67.                comptype:byte;
  68.                option:set of opts;
  69.                vote:array[1..9] of byte;
  70.                sbn:byte;
  71.                dsl:byte;
  72.                uploads,downloads:integer;
  73.                uk,dk:integer;
  74.              end;
  75.       boardrec=record
  76.                  name:string[25];
  77.                  filename:string[12];
  78.                  sl:byte;
  79.                  maxmsgs:byte;
  80.                  pw:string[10];
  81.                  anonymous:anontyp;
  82.                  ar:acrq;
  83.                  key:char;
  84.                end;
  85.       msgstat=(validated,unvalidated,deleted);
  86.       messagerec=record
  87.                    title:string[30];
  88.                    messagestat:msgstat;
  89.                    message:messages;
  90.                    owner:integer;
  91.                    date:integer;
  92.                    mage:byte;
  93.                  end;
  94.       systatrec=record
  95.                   boardpw:string[8];
  96.                   sysoppw:string[8];
  97.                   hmsg:messages;
  98.                   users:integer;
  99.                   lastdate:string[8];
  100.                   callernum:integer;
  101.                   activetoday:integer;
  102.                   callstoday:integer;
  103.                   msgposttoday:integer;
  104.                   emailtoday:integer;
  105.                   fbacktoday:integer;
  106.                   uptoday:integer;
  107.                   closedsystem:boolean;
  108.                 end;
  109.       blk=array[1..255] of byte;
  110.       mailrec=record
  111.                 title:string[30];
  112.                 from,destin:integer;
  113.                 msg:messages;
  114.                 date:integer;
  115.                 mage:byte;
  116.               end;
  117.       gft=record
  118.             num:integer;
  119.             title:string[40];
  120.             filen:string[12];
  121.           end;
  122.       charfil=text;
  123.       smr=record
  124.             msg:str;
  125.             destin:integer;
  126.           end;
  127.       vdatar=record
  128.                question:string[79];
  129.                numa:integer;
  130.                answ:array[0..9] of record
  131.                       ans:string[25];
  132.                       numres:integer;
  133.                     end;
  134.              end;
  135.       regs=record ax,bx,cx,dx,bp,si,di,ds,es,flags:integer; end;
  136.       ulrec=record
  137.               name:string[25];
  138.               filename:string[12];
  139.               password:string[10];
  140.               dsl:byte;
  141.               maxfiles:integer;
  142.             end;
  143.       ulfrec=record
  144.                filename:string[12];
  145.                description:string[60];
  146.                res:array[1..17] of byte;
  147.                ft:array[1..3] of byte;
  148.                blocks:integer;
  149.                owner:integer;
  150.                date:string[8];
  151.                daten:integer;
  152.              end;
  153.  
  154. var sf:file of smalrec;
  155.     uf:file of userrec;
  156.     bf:file of boardrec;
  157.     mf:file of messagerec;
  158.     mailfile:file of mailrec;
  159.     sysopf:charfil;
  160.     slf:file of slr;
  161.     seclev:array[0..255] of slr;
  162.     systatf:file of systatrec;
  163.     systat:systatrec;
  164.     sr:smalrec;
  165.     thisline,chatr,buf,spd,irt,lastname,ll,cursor,i:str;
  166.     thisuser,user:userrec;
  167.     boards:array[1..19] of boardrec;
  168.     fw,extramsgs,mread,board,numboards,t,usernum:integer;
  169.     pap,lil,realsl,ftoday,ptoday,etoday:integer;
  170.     c,ID:char;
  171.     hungup,useron,next,chatcall,expert,doneday,echo,hangup,incom,outcom:boolean;
  172.     extratime,timeon:real;
  173.     macok,lan,enddayf,ch,quit:boolean;
  174.     buffer:Array[0..buffer_Max] of Char;
  175.     comport,base:Integer;
  176.     Async_Irq:Integer;
  177.     buffer_Head,buffer_tail,buffer_newtail:Integer;
  178.     smf:file of smr;
  179.     srl:array[0..maxusers] of smalrec;
  180.     vqu:array[1..9] of boolean;
  181.     ret:byte absolute cseg:$0080;
  182.     ldate1:integer;
  183.     maxspd:integer;
  184.     cmd:char;
  185.     help:array[1..25000] of char;
  186.     helpi:array['0'..'^'] of integer;
  187.     helpl:char;
  188.     ihelp:boolean;
  189.     cf:text; cfo,okt:boolean;
  190.     ulf:file of ulrec;
  191.     uboards:array[0..19] of ulrec;
  192.     ulff:file of ulfrec;
  193.     crc,culb,maxulb:integer;
  194.     sortbd,doneft:boolean;
  195.     ldate:str;
  196.     ymodem,ucrc,bnp:boolean;
  197.     chksum:byte;
  198.     lrn:integer;
  199.     lfn:str;
  200.     ft:byte;
  201.  
  202. label reent;
  203.  
  204. {$I COMMON.PAS}
  205.  
  206. procedure printfile(fn:str);
  207. var fil:text;
  208.     i:str;
  209.     abort,next:boolean;
  210. begin
  211.  if not hangup then begin
  212.   assign(fil,fn);
  213.   {$I-} reset(fil); {$I+}
  214.   if ioresult<>0 then print('File not found.') else begin
  215.     abort:=false;
  216.     while not eof(fil) and (not abort) and (not hangup) do begin
  217.       readln(fil,i);
  218.       if i[length(i)]<>#1 then i:=i+#1;
  219.       printa(i,abort,next);
  220.     end;
  221.     close(fil);
  222.   end;
  223.   nl;nl;
  224.  end;
  225. end;
  226.  
  227. function tcheck(s:real; i:integer):boolean;
  228. var r:real;
  229. begin
  230.   r:=timer;
  231.   if r<s then r:=r+86400.0;
  232.   if trunc(r-s)>i then tcheck:=false else tcheck:=true;
  233. end;
  234.  
  235. function tchk(s:real; i:real):boolean;
  236. var r:real;
  237. begin
  238.   r:=timer;
  239.   if r<s then r:=r+86400.0;
  240.   if (r-s)>i then tchk:=false else tchk:=true;
  241. end;
  242.  
  243. {$I DLP1.PAS}
  244.  
  245. procedure i1;
  246. begin
  247.   assign(ulf,'gfiles\uploads.dat');
  248.   reset(ulf); maxulb:=-1;
  249.   while not eof(ulf) do begin maxulb:=maxulb+1; read(ulf,uboards[maxulb]); end;
  250.   close(ulf);
  251.   culb:=1;
  252.   ldate:=thisuser.laston;
  253. end;
  254.  
  255. function exist(fn:str):boolean;
  256. var f:file;
  257. begin
  258.   assign(f,fn);
  259.   {$I-} reset(f); {$I+}
  260.   if ioresult=0 then begin close(f); exist:=true end else exist:=false;
  261. end;
  262.  
  263. function align(fn:str):str;
  264. var f,e,t:str; c,c1:integer;
  265. begin
  266.   c:=pos('.',fn);
  267.   if c=0 then begin
  268.     f:=fn; e:='   ';
  269.   end else begin
  270.     f:=copy(fn,1,c-1); e:=copy(fn,c+1,3);
  271.   end;
  272.   while length(f)<8 do f:=f+' ';
  273.   while length(e)<3 do e:=e+' ';
  274.   if length(f)>8 then f:=copy(f,1,8);
  275.   if length(e)>3 then e:=copy(e,1,3);
  276.   c:=pos('*',f); if c<>0 then for c1:=c to 8 do f[c1]:='?';
  277.   c:=pos('*',e); if c<>0 then for c1:=c to 3 do e[c1]:='?';
  278.   c:=pos(' ',f); if c<>0 then for c1:=c to 8 do f[c1]:=' ';
  279.   c:=pos(' ',e); if c<>0 then for c1:=c to 3 do e[c1]:=' ';
  280.   align:=f+'.'+e;
  281. end;
  282.  
  283. function fit(f1,f2:str):boolean;
  284. var tf:boolean; c:integer;
  285. begin
  286.   tf:=true;
  287.   for c:=1 to 12 do
  288.     if (f1[c]<>f2[c]) and (f1[c]<>'?') then tf:=false;
  289.   fit:=tf;
  290. end;
  291.  
  292. procedure iscan(var pl:integer);
  293. var f:ulfrec;
  294. begin
  295.   assign(ulff,'gfiles\'+uboards[culb].filename);
  296.   {$I-} reset(ulff); {$I+}
  297.   if ioresult<>0 then begin
  298.     rewrite(ulff);
  299.     f.blocks:=0;
  300.     write(ulff,f);
  301.   end;
  302.   seek(ulff,0);
  303.   read(ulff,f);
  304.   pl:=f.blocks;
  305.   bnp:=false;
  306. end;
  307.  
  308. procedure recno(fn:str; var pl,rn:integer);
  309. var c:integer;
  310.     f:ulfrec;
  311. begin
  312.   fn:=align(fn);
  313.   iscan(pl); rn:=0; c:=1;
  314.   while (c<=pl) and (rn=0) do begin
  315.     seek(ulff,c); read(ulff,f);
  316.     if fit(fn,align(f.filename)) then rn:=c;
  317.     c:=c+1;
  318.   end;
  319.   lrn:=rn;
  320.   lfn:=fn;
  321. end;
  322.  
  323. procedure nrecno(fn:str; var pl,rn:integer);
  324. var c:integer;
  325.     f:ulfrec;
  326. begin
  327.   fn:=align(fn);
  328.   if fn=lfn then begin
  329.     if (lrn<pl) and (lrn>0) then begin
  330.       c:=lrn+1; rn:=0;
  331.       while (c<=pl) and (rn=0) do begin
  332.         seek(ulff,c); read(ulff,f);
  333.         if fit(fn,align(f.filename)) then rn:=c;
  334.         c:=c+1;
  335.       end;
  336.       lrn:=rn;
  337.     end else rn:=0;
  338.   end else rn:=0;
  339. end;
  340.  
  341. procedure arcl(fn:str; var abort:boolean);
  342. type ei=record l,h:integer; end;
  343.      archead=record
  344.                name:array[1..13] of char;
  345.                size:ei;
  346.                date,time,crc:integer;
  347.                len:ei;
  348.              end;
  349. var f:file; b:byte;
  350.     head:archead;
  351.     done,next:boolean;
  352.  
  353.   function valueei(x:ei):real;
  354.   var r:real; tf:boolean;
  355.   begin
  356.     if x.h>=0 then begin r:=int(x.h)*65536.0; tf:=true; end else
  357.       begin tf:=false; if x.h=$8000 then r:=65536.0*65536.0 else
  358.         r:=int(-x.h)*65536.0; end;
  359.     if x.l>=0 then r:=r+int(x.l)
  360.     else if x.l=$8000 then r:=r+32760.0
  361.     else r:=r+65536.0+x.l;
  362.     if tf then valueei:=r else valueei:=-r;
  363.   end;
  364.  
  365.   procedure pfn;
  366.   var i,i1:str; try:byte;
  367.   begin
  368.     b:=0; try:=0;
  369.     while not eof(f) and (b<>26) and (try<5) do begin
  370.       blockread(f,b,1);
  371.       try:=try+1;
  372.     end;
  373.     if try>=5 then longseek(f,filesize(f)-2.0);
  374.     if longfilepos(f)+27<longfilesize(f) then begin
  375.       blockread(f,b,1);
  376.       if b<>0 then begin
  377.           if b=1 then begin
  378.           blockread(f,head,sizeof(head)-sizeof(ei));
  379.           head.len:=head.size;
  380.         end else blockread(f,head,sizeof(head));
  381.         i:=''; b:=1;
  382.         while (head.name[b]<>#0) and (b<=13) do begin
  383.           i:=i+head.name[b];
  384.           b:=b+1;
  385.         end;
  386.         i:=align(i)+' ';
  387.         i1:=cstrr(valueei(head.len));
  388.         while length(i1)<7 do i1:=' '+i1;
  389.         i:=i+i1;
  390.         printacr(i,abort,next);
  391.       end else done:=true;
  392.       longseek(f,longfilepos(f)+valueei(head.size));
  393.     end;
  394.   end;
  395.  
  396. begin
  397.   assign(f,fn);
  398.   reset(f,1); done:=false;
  399.   while (longfilepos(f)+27.0<longfilesize(f)) and not (abort or done) do
  400.     pfn;
  401.   close(f);
  402. end;
  403.  
  404. procedure lbrl(fn:str; var abort:boolean);
  405. var f:file;
  406.     c,n,n1:integer;
  407.     x:record
  408.         st:byte;
  409.         name:array[1..8] of char;
  410.         ext:array[1..3] of char;
  411.         index,len:integer;
  412.         fil:array[1..16] of byte;
  413.       end;
  414.     next:boolean;
  415.     i,i1:str;
  416.  
  417. begin
  418.   assign(f,fn);
  419.   reset(f,32);
  420.   blockread(f,x,1);
  421.   c:=x.len*4-1;
  422.   for n:=1 to c do begin
  423.     blockread(f,x,1); i:='';
  424.     if (x.st=0) and not abort then begin
  425.       for n1:=1 to 8 do i:=i+x.name[n1];
  426.       i:=i+'.';
  427.       for n1:=1 to 3 do i:=i+x.ext[n1];
  428.       i:=align(i)+' ';
  429.       i1:=cstrr(x.len*128.0);
  430.       while length(i1)<7 do i1:=' '+i1;
  431.       i:=i+i1;
  432.       printacr(i,abort,next);
  433.     end;
  434.   end;
  435.   close(f);
  436. end;
  437.  
  438. procedure lfi(fn:str; var abort:boolean);
  439. var next:boolean; i1,i2:str;
  440. begin
  441.   if exist('dloads\'+fn) and (not abort) then
  442.     if (pos('.ARC',fn)<>0) or (pos('.LBR',fn)<>0) then begin
  443.       nl;
  444.       i1:=align(fn); i2:=''; while length(i1)>length(i2) do i2:=i2+'-';
  445.       printacr(i1,abort,next);
  446.       printacr(i2,abort,next);
  447.       nl;
  448.       if not abort then begin
  449.         if pos('.ARC',fn)<>0 then arcl('dloads\'+fn,abort);
  450.         if pos('.LBR',fn)<>0 then lbrl('dloads\'+fn,abort);
  451.       end;
  452.       nl;
  453.     end;
  454. end;
  455.  
  456. procedure lfin(rn:integer; var abort:boolean);
  457. var f:ulfrec;
  458. begin
  459.   seek(ulff,rn); read(ulff,f); lfi(f.filename,abort);
  460. end;
  461.  
  462. procedure lfii;
  463. var fn:str; pl,rn:integer; abort:boolean;
  464. begin
  465.   helpl:='[';
  466.   nl; print('Enter file to list interior files of');
  467.   prompt(': '); input(fn,12);
  468.   recno(fn,pl,rn);
  469.   abort:=false;
  470.   if rn=0 then print('File not found.') else begin
  471.     while (rn<>0) and (not abort) do begin
  472.       lfin(rn,abort);
  473.       nrecno(fn,pl,rn);
  474.     end;
  475.   end;
  476.   close(ulff);
  477. end;
  478.  
  479. procedure return;
  480. var f:file;
  481. begin
  482.   assign(f,'bbs.com');
  483.   print('Returning to BBS...');
  484.   remove_port;
  485.   if hangup then term_ready(false);
  486.   execute(f);
  487. end;
  488.  
  489.  
  490. procedure pbn(var abort:boolean);
  491. var i,i1:str; next:boolean;
  492. begin
  493.   if not bnp then begin
  494.     nl;
  495.     i:=uboards[culb].name+' #'+cstr(culb);
  496.     i1:='---'; while length(i1)<length(i) do i1:=i1+'-';
  497.     nl; nl;
  498.     printacr(i,abort,next);
  499.     printacr(i1,abort,next);
  500.     nl;
  501.   end;
  502.   bnp:=true;
  503. end;
  504.  
  505.  
  506. function uc(s:str):str;
  507. var x:str; i:integer;
  508. begin
  509.   x:=s;
  510.   for i:=1 to length(s) do
  511.     x[i]:=upcase(x[i]);
  512.   uc:=x;
  513. end;
  514.  
  515. procedure dlx(f1:ulfrec; var abort:boolean);
  516. var inte,pl,c:integer; ok,tl:boolean; u:userrec; rl:real; i,ii:str;
  517. begin
  518.     nl; nl;
  519.     print('Filename: "'+align(f1.filename)+'"');
  520.     print('Desc.   : '+f1.description);
  521.     print('# blocks: '+cstr(f1.blocks)+'-'+cstr((f1.blocks+7)div 8));
  522.     inte:=value(spd); if inte=0 then inte:=1200;
  523.     rl:=1620.0*f1.blocks/inte;
  524.     if rl>32767.0 then rl:=32000; if rl<0.0 then rl:=0;
  525.     inte:=trunc(rl);
  526.     i:=cstr(inte div 3600)+':'; ii:=cstr((inte mod 3600) div 60);
  527.     if length(ii)=1 then ii:='0'+ii; i:=i+ii+':';
  528.     ii:=cstr(inte mod 60); if length(ii)=1 then ii:='0'+ii;
  529.     i:=i+ii; print('apx time: '+i);
  530.     reset(uf); seek(uf,f1.owner); read(uf,u); close(uf);
  531.     print('U/L by  : '+u.name+' #'+cstr(f1.owner));
  532.     print('U/L on  : '+f1.date);
  533.     ft:=255; if (f1.ft[1]=$81) and (f1.ft[2]=$f5) then ft:=f1.ft[3];
  534.     if ft<>255 then print('File typ: '+cstr(ft));
  535.     if timer<timeon then timeon:=timeon-24.0*60*60;
  536.     tl:=((seclev[thisuser.sl].ttime*60+extratime+timeon-timer-rl)>0);
  537.     if tl or (copy(f1.filename,1,4)='WWIV') then begin
  538.       if exist('dloads\'+f1.filename) then
  539.         send1('dloads\'+f1.filename,ok,abort)
  540.       else print('File isn''t really there!');
  541.     end else print('Not enough time left to D/L');
  542. end;
  543.  
  544. procedure dl(fn:str);
  545. var pl,rn:integer; f:ulfrec; abort:boolean;
  546. begin
  547.   recno(fn,pl,rn); abort:=false;
  548.   if rn=0 then print('File not found.') else begin
  549.     while (rn<>0) and (not abort) do begin
  550.       seek(ulff,rn); read(ulff,f); dlx(f,abort);
  551.       nrecno(fn,pl,rn);
  552.     end;
  553.   end;
  554.   close(ulff);
  555. end;
  556.  
  557. procedure dl1(n:integer);
  558. var f1:ulfrec; abort:boolean;
  559. begin
  560.   nl; nl;
  561.   seek(ulff,n); read(ulff,f1);
  562.   dlx(f1,abort);
  563.   nl;
  564. end;
  565.  
  566.  
  567. procedure ul(fn:str);
  568. var x,pl,c,cc,ob,np:integer; f,f1:ulfrec; uls,ok:boolean; fi:file of byte;
  569. begin
  570.   uls:=incom;
  571.   ob:=culb;
  572.   ok:=true; fn:=align(fn);
  573.   if (fn[1]=' ') or (fn[10]=' ') then ok:=false;
  574.   for x:=1 to length(fn) do
  575.     if not (fn[x] in ['0'..'9','A'..'Z','.',' ']) then ok:=false;
  576.   np:=0; for x:=1 to length(fn) do if fn[x]='.' then np:=np+1;
  577.   if np<>1 then ok:=false;
  578.   if ok then
  579.     if incom then
  580.       if exist('dloads\'+fn) then
  581.         if cs then begin
  582.           print('There already is one.');
  583.           prompt('Do it anyways? ');
  584.           ok:=yn;
  585.           uls:=false;
  586.         end else
  587.           ok:=false
  588.       else
  589.         ok:=true
  590.     else
  591.       ok:=exist('dloads\'+fn)
  592.   else print('Illegal filename.');
  593.   if (not incom) then
  594.     if ok then print('Am using the file in dloads\')
  595.     else begin print('To put in a file from keyboard, it must already be');
  596.                print('present in the dloads\ directory.'); end;
  597.   nl; nl;
  598.   if ok and incom and uls then begin
  599.     assign(fi,'dloads\'+fn); {$I-} rewrite(fi); {$I+}
  600.     if ioresult<>0 then begin
  601.       {$I-} close(fi); {$I+} cc:=ioresult;
  602.       ok:=false;
  603.     end else begin close(fi); erase(fi); end;
  604.   end;
  605.   if not ok then print('Can''t use that filename, sorry.') else begin
  606.     iscan(pl);
  607.     if pl>=uboards[culb].maxfiles then print('This board is full.') else begin
  608.       prompt('Upload "'+fn+'" ? ');
  609.       if yn then begin ok:=true; close(ulff);
  610.         nl; print('Please enter a one line description.'); prompt(':');
  611.         inputl(f.description,60);
  612.         if (f.description[1]='\') or (rvalidate in thisuser.ac) then culb:=0;
  613.         if f.description[1]='\' then f.description:=copy(f.description,2,80);
  614.         iscan(pl);
  615.         ok:=true; ft:=255;
  616.         if uls then receive1('dloads\'+fn,ok);
  617.         nl; nl;
  618.         if not ok then print('Not saved.') else begin
  619.           f.filename:=fn;
  620.           f.owner:=usernum;
  621.           f.date:=date;
  622.           f.daten:=daynum(date);
  623.           for x:=1 to 17 do f.res[x]:=0;
  624.           for x:=1 to 3 do f.ft[x]:=0;
  625.           if ft<>255 then begin
  626.             f.ft[1]:=$81; f.ft[2]:=$f5; f.ft[3]:=ft;
  627.           end;
  628.           assign(fi,'dloads\'+fn);
  629.           {$I-} reset(fi); {$I+}
  630.           if ioresult=0 then begin
  631.             f.blocks:=trunc((longfilesize(fi)+127.0)/128.0);
  632.             close(fi);
  633.             for x:=pl downto 1 do begin
  634.               seek(ulff,x); read(ulff,f1);
  635.               seek(ulff,x+1); write(ulff,f1);
  636.             end;
  637.             seek(ulff,1);
  638.             write(ulff,f);
  639.             seek(ulff,0); read(ulff,f); f.blocks:=pl+1;
  640.             seek(ulff,0); write(ulff,f);
  641.             sysoplog('Uploaded "'+fn+'" on '+uboards[culb].name);
  642.             print('File successfully uploaded.');
  643.           end else begin
  644.             print('Oops, system error.  Not saved.');
  645.             sysoplog('Error uploading "'+fn+'"');
  646.           end;
  647.         end;
  648.       end;
  649.     end;
  650.     close(ulff); culb:=ob;
  651.   end;
  652.   nl; nl;
  653. end;
  654.  
  655. procedure idl;
  656. var i:str;
  657. begin
  658.   helpl:='X';
  659.   nl; print('Download -'); nl; prompt('Enter filename: '); input(i,12);
  660.   dl(i);
  661.   nl; nl;
  662. end;
  663.  
  664. procedure iul;
  665. var i:str;
  666. begin
  667.   helpl:='U';
  668.   nl; nl; print('Upload -'); nl; prompt('Enter filename: '); input(i,12);
  669.   ul(i);
  670.   nl; nl;
  671. end;
  672.  
  673. procedure gfn(var fn:str);
  674. begin
  675.   nl; helpl:='L';
  676.   prompt('File mask: '); input(fn,12);
  677.   if fn='' then fn:='*.*';
  678.   fn:=align(fn);
  679. end;
  680.  
  681. function aln(i:str; n:integer):str;
  682. begin
  683.   while length(i)<n do i:=' '+i;
  684.   aln:=i;
  685. end;
  686.  
  687. procedure pfn(f:ulfrec; var abort,next:boolean);
  688. begin
  689.   printacr(align(f.filename)+':'+aln(cstr(f.blocks),4)+' :'+f.description,abort,next);
  690. end;
  691.  
  692. procedure searchb(b:integer; fn:str; var abort:boolean);
  693. var oldboard,pl,rn:integer; f:ulfrec;
  694. begin
  695.   oldboard:=culb; culb:=b;
  696.   recno(fn,pl,rn);
  697.   while (rn<=pl) and (not abort) and (not hangup) and (rn<>0) do begin
  698.     seek(ulff,rn); read(ulff,f);
  699.     pbn(abort);
  700.     pfn(f,abort,next);
  701.     nrecno(fn,pl,rn);
  702.   end;
  703.   close(ulff);
  704.   culb:=oldboard;
  705. end;
  706.  
  707. procedure searchbd(b:integer; ts:str; var abort:boolean);
  708. var oldboard,pl,rn:integer; f:ulfrec; next:boolean;
  709. begin
  710.   oldboard:=culb; culb:=b; iscan(pl);
  711.   rn:=1;
  712.   while (rn<=pl) and (not abort) and (not hangup) do begin
  713.     seek(ulff,rn); read(ulff,f);
  714.     if pos(ts,uc(f.description))<>0 then begin
  715.       pbn(abort);
  716.       pfn(f,abort,next);
  717.     end;
  718.     rn:=rn+1;
  719.   end;
  720.   close(ulff);
  721.   culb:=oldboard;
  722. end;
  723.  
  724. procedure search;
  725. var fn:str; bn:integer; abort:boolean;
  726. begin
  727.   nl; nl; print('Search all directories.');
  728.   gfn(fn);
  729.   if cs then bn:=0 else bn:=1; abort:=false;
  730.   while (not abort) and (bn<=maxulb) and (not hangup) do begin
  731.     if uboards[bn].dsl<=thisuser.dsl then searchb(bn,fn,abort);
  732.     bn:=bn+1;
  733.   end;
  734. end;
  735.  
  736. procedure searchd;
  737. var fn:str; bn:integer; abort:boolean;
  738. begin
  739.   nl; nl; print('Find a description -'); nl;
  740.   print('Enter what to search description for.');
  741.   helpl:='Y';
  742.   prompt(': '); input(fn,20);
  743.   if fn<>'' then begin
  744.     nl; print('Searching for "'+fn+'"'); nl;
  745.     prompt('Search all directories? ');
  746.     if yn then begin
  747.       if cs then bn:=0 else bn:=1; abort:=false;
  748.       while (not abort) and (bn<=maxulb) and (not hangup) do begin
  749.         if uboards[bn].dsl<=thisuser.dsl then searchbd(bn,fn,abort);
  750.         bn:=bn+1;
  751.       end;
  752.     end else searchbd(culb,fn,abort);
  753.   end;
  754. end;
  755.  
  756. procedure newfiles(b:integer; var abort:boolean);
  757. var oldboard,pl,rn,ldn:integer; f:ulfrec; next:boolean;
  758. begin
  759.   oldboard:=culb; culb:=b; iscan(pl);
  760.   ldn:=daynum(ldate);
  761.   rn:=1;
  762.   while (rn<=pl) and (not abort) and (not hangup) do begin
  763.     seek(ulff,rn); read(ulff,f);
  764.     if f.daten>=ldn then begin
  765.       pbn(abort);
  766.       pfn(f,abort,next);
  767.     end;
  768.     rn:=rn+1;
  769.   end;
  770.   close(ulff);
  771.   culb:=oldboard;
  772. end;
  773.  
  774. procedure nf;
  775. var bn:integer; abort:boolean;
  776. begin
  777.   nl; print('Search for new files.'); nl;
  778.   prompt('Search all directories? ');
  779.   if yn then begin
  780.     if cs then bn:=0 else bn:=1; abort:=false;
  781.     while (not abort) and (bn<=maxulb) and (not hangup) do begin
  782.       if uboards[bn].dsl<=thisuser.dsl then newfiles(bn,abort);
  783.       bn:=bn+1;
  784.     end;
  785.   end else newfiles(culb,abort);
  786. end;
  787.  
  788. procedure delete(rn:integer; var pl:integer);
  789. var f:ulfrec; i:integer;
  790. begin
  791.   if (rn<=pl) and (rn>0) then begin
  792.     pl:=pl-1;
  793.     for i:=rn to pl do begin
  794.       seek(ulff,i+1); read(ulff,f);
  795.       seek(ulff,i); write(ulff,f);
  796.     end;
  797.     seek(ulff,0); f.blocks:=pl; write(ulff,f);
  798.   end;
  799. end;
  800.  
  801. procedure remove;
  802. var pl,c,rn:integer; f:ulfrec; fn:str; ff:file; u:userrec; tf:boolean;
  803. begin
  804.   print('Enter filename to remove.'); prompt(': ');
  805.   input(fn,12);
  806.   if fn<>'' then begin
  807.     recno(fn,pl,rn);
  808.     if rn<>0 then begin
  809.       seek(ulff,rn); read(ulff,f);
  810.       if (usernum=f.owner) or cs then begin
  811.         print('Filename: "'+f.filename+'"');
  812.         print('Desc.   : '+f.description);
  813.         print('# blocks: '+cstr(f.blocks));
  814.         reset(uf); seek(uf,f.owner); read(uf,u); close(uf);
  815.         print('U/L by  : '+u.name+' #'+cstr(f.owner));
  816.         print('U/L on  : '+f.date);
  817.         prompt('Delete this? ');
  818.         if yn then begin
  819.           delete(rn,pl);
  820.           if cs then begin
  821.             prompt('Erase file too? ');
  822.             tf:=yn;
  823.           end else tf:=true;
  824.           if tf then begin
  825.             assign(ff,'dloads\'+fn);
  826.             {$I-} erase(ff); {$I+}
  827.             c:=ioresult;
  828.           end;
  829.         end;
  830.       end;
  831.     end;
  832.     close(ulff);
  833.   end;
  834.   nl; nl;
  835. end;
  836.  
  837. procedure move;
  838. var pl,c,rn,int,dbn:integer; f:ulfrec; fn:str; ff:file; i:str;
  839. begin
  840.   print('Enter filename to move.'); prompt(': ');
  841.   input(fn,12);
  842.   if fn<>'' then begin
  843.     recno(fn,pl,rn);
  844.     if rn<>0 then begin
  845.       seek(ulff,rn); read(ulff,f);
  846.       print(align(f.filename)+' : '+f.description); nl; nl;
  847.       prompt('Move this? ');
  848.       if yn then begin
  849.         nl;
  850.         for int:=0 to maxulb do
  851.           print(cstr(int)+' : '+uboards[int].name);
  852.         nl; nl;
  853.         prompt('To which directory? '); input(i,3);
  854.         dbn:=value(i); if (dbn=0) and (i<>'0') then dbn:=-1;
  855.         if (dbn<0) or (dbn>maxulb) then print('Can''t move it there.')
  856.         else begin
  857.           delete(rn,pl);
  858.           close(ulff);
  859.           int:=culb; culb:=dbn; iscan(pl);
  860.           seek(ulff,pl+1); write(ulff,f);
  861.           seek(ulff,0); f.blocks:=pl+1; write(ulff,f);
  862.           culb:=int;
  863.         end;
  864.       end;
  865.     end;
  866.     close(ulff);
  867.   end;
  868. end;
  869.  
  870. procedure ren;
  871. var pl,c,rn,int,dbn:integer; f:ulfrec; fn,fd:str; ff:file; i:str;
  872. begin
  873.   print('Enter filename to rename.'); prompt(': ');
  874.   input(fn,12); nl; nl;
  875.   if fn<>'' then begin
  876.     recno(fn,pl,rn);
  877.     if rn<>0 then begin
  878.       seek(ulff,rn); read(ulff,f);
  879.       print(align(f.filename)+' : '+f.description); nl; nl;
  880.       prompt('Rename this stuff? ');
  881.       if yn then begin
  882.         prompt('New filename? '); input(fn,12);
  883.         if fn<>'' then begin
  884.           if exist('dloads\'+fn) then print('Can''t use that filename.') else begin
  885.             chdir('dloads'); assign(ff,f.filename); rename(ff,fn); chdir('..');
  886.             f.filename:=fn;
  887.           end;
  888.         end;
  889.         print('New description -'); prompt(': '); inputl(fd,60);
  890.         if fd<>'' then f.description:=fd;
  891.         seek(ulff,rn); write(ulff,f);
  892.       end;
  893.     end;
  894.     close(ulff);
  895.   end;
  896. end;
  897.  
  898. function gtr(f,f1:ulfrec):boolean;
  899. begin
  900.   if sortbd and (f1.daten<>f.daten) then
  901.     if f1.daten<f.daten then
  902.       gtr:=false
  903.     else
  904.       gtr:=true
  905.   else
  906.     if f1.filename>f.filename then
  907.       gtr:=false
  908.     else
  909.       gtr:=true;
  910. end;
  911.  
  912. procedure sortd(c:integer);
  913. var oldboard,trn,srn,i,i1,pl:integer; f,f1:ulfrec;
  914. begin
  915.   oldboard:=culb; culb:=c; iscan(pl);
  916.   nl; print('Sorting '+uboards[culb].name);
  917.   for i:=1 to pl-1 do begin
  918.     seek(ulff,i); read(ulff,f); trn:=i;
  919.     for i1:=i+1 to pl do begin
  920.       seek(ulff,i1); read(ulff,f1);
  921.       if gtr(f,f1) then begin
  922.         f:=f1; trn:=i1;
  923.       end;
  924.     end;
  925.     seek(ulff,i); read(ulff,f1); seek(ulff,i);
  926.     write(ulff,f); seek(ulff,trn); write(ulff,f1);
  927.   end;
  928.   close(ulff);
  929.   culb:=oldboard;
  930. end;
  931.  
  932. procedure sort;
  933. var bn:integer;
  934. begin
  935.   nl; nl; prompt('Sort by date? '); if yn then sortbd:=true else sortbd:=false;
  936.   nl; prompt('Sort all boards? ');
  937.   if yn then
  938.     for bn:=0 to maxulb do
  939.       sortd(bn)
  940.   else
  941.     sortd(culb);
  942. end;
  943.  
  944. procedure listfiles;
  945. var abort:boolean; fn:str;
  946. begin
  947.   nl; nl; print('List files.');
  948.   gfn(fn); abort:=false;
  949.   searchb(culb,fn,abort);
  950. end;
  951.  
  952. procedure listf(n:integer; var abort:boolean);
  953. var f:ulfrec; i,i1:str; next:boolean;
  954. begin
  955.   seek(ulff,n); read(ulff,f);
  956.   i:=cstr(n); while length(i)<3 do i:=' '+i;
  957.   i:=i+': '+align(f.filename);
  958.   while length(i)<20 do i:=i+' ';
  959.   i1:=cstr(f.blocks); while length(i1)<5 do i1:=' '+i1; i:=i+i1;
  960.   i:=i+'  '+f.date+'  '; i1:=cstr(f.owner); while length(i1)<3 do i1:=' '+i1;
  961.   i:=i+i1;
  962.   printacr(i,abort,next);
  963. end;
  964.  
  965. procedure browsefiles;
  966. var pl,n,nfl,cn:integer; f:ulfrec; i,i1:str; abort,next,list,done:boolean;
  967. begin
  968.   iscan(pl); nl; nl; helpl:='B';
  969.     print('('+uboards[culb].name+') - '+cstr(pl)+' files');
  970.     if pl<>0 then begin
  971.     nl; abort:=false; done:=false;
  972.     prompt('Start at? '); input(i,3); cn:=value(i); if cn=0 then cn:=1;
  973.     if i='Q' then cn:=0; if cn>pl then cn:=0;
  974.     if cn>0 then begin list:=true;
  975.       repeat
  976.         tleft;
  977.         if list then begin
  978.           if cn>pl then cn:=1;
  979.           nfl:=0;
  980.           print(' NN: filename.ext   blcks  mm/dd/yy  frm');
  981.           while (not hangup) and (nfl<10) and (not abort) and (cn<=pl) do begin
  982.             listf(cn,abort); cn:=cn+1; nfl:=nfl+1;
  983.           end;
  984.           list:=false;
  985.         end;
  986.         nl; prompt('Browse: (1-'+cstr(pl)+',^'+cstr(cn)+'),U,D,Q,L,? :');
  987.         input(i,3); n:=0;
  988.         if (i='') and (cn>pl) then i:='Q';
  989.         n:=value(i); if (n>0) and (n<=pl) then begin cn:=n; i:='D'; end;
  990.         if i='?' then begin print('U:pload     D:ownload');
  991.                             print('Q:uit       L:ist files'); end;
  992.         if i='Q' then done:=true;
  993.         if i='L' then list:=true;
  994.         if i='U' then begin close(ulff); iul; iscan(pl); end;
  995.         if i='D' then begin
  996.           if n=0 then begin print('Download -'); nl; prompt('Which number? ');
  997.             input(i1,3); n:=value(i1); end;
  998.           if (n>0) and (n<=pl) then dl1(n);
  999.         end;
  1000.       until done or hangup;
  1001.     end;
  1002.   end;
  1003.   close(ulff);
  1004. end;
  1005.  
  1006. procedure pointdate;
  1007. var i:str; n:integer;
  1008. begin
  1009.   nl; nl; nl; helpl:='P';
  1010.   print('Enter limiting date for new files -');
  1011.   print('Date is currently set to '+ldate);
  1012.   print(' mm/dd/yy');
  1013.   prompt(':'); input(i,8);
  1014.   nl; nl;
  1015.   n:=daynum(i);
  1016.   if n=0 then
  1017.     print('Illegal date.')
  1018.   else
  1019.     ldate:=i;
  1020.   nl; print('Current limiting date is '+ldate);
  1021. end;
  1022.  
  1023. procedure listboards;
  1024. var b:integer; i:str; abort,next:boolean;
  1025. begin
  1026.   nl;nl; print('Directories available to you:'); nl; nl;
  1027.   b:=1; abort:=false;
  1028.   while (b<=maxulb) and (not abort) and (not hangup) do begin
  1029.     if uboards[b].dsl<=thisuser.dsl then begin
  1030.        i:=cstr(b);
  1031.        if length(i)=1 then i:=' '+i;
  1032.        i:=i+' : '+uboards[b].name;
  1033.        printacr(i,abort,next);
  1034.     end;
  1035.     b:=b+1;
  1036.   end;
  1037.   nl;nl;
  1038. end;
  1039.  
  1040. procedure mmkey(var i:str);
  1041. var c:char;
  1042. begin
  1043.   repeat
  1044.     repeat
  1045.       getkey(c);
  1046.       if c=#26 then phelp;
  1047.       skey(c);
  1048.     until (((c>=' ') and (c<chr(127))) or (c=chr(13))) or hangup;
  1049.     c:=upcase(c);
  1050.     outkey(c);
  1051.     thisline:=thisline+c;
  1052.     if (c='/') or (c='1') then begin
  1053.       i:=c;
  1054.       repeat
  1055.         getkey(c);
  1056.         if c=#26 then phelp;
  1057.         skey(c);
  1058.       until ((c>=' ')and(c<=chr(127))) or (c=chr(13)) or (c=chr(8)) or hangup;
  1059.       c:=upcase(c);
  1060.       if c<>chr(13) then begin outkey(c); thisline:=thisline+c; end;
  1061.       if (c=chr(8)) or (c=chr(127)) then prompt(' '+c);
  1062.       if c='/' then input(i,20) else if c<>chr(13) then i:=i+c;
  1063.     end else i:=c;
  1064.   until (c<>chr(8)) and (c<>chr(127)) or hangup;
  1065.   nl;
  1066. end;
  1067.  
  1068. procedure reqchat;
  1069. begin
  1070.   nl;nl; if (not sysop) or (rchat in thisuser.ac)
  1071.   then begin
  1072.     print('Sysop not available.');
  1073.   end else begin
  1074.     if not chatcall then begin
  1075.       helpl:='C'; prompt('Reason: '); inputl(i,70);
  1076.       if i<>'' then begin
  1077.         sysoplog('Chat: '+i);
  1078.         print('Chat call now on.');
  1079.         sound(440); delay(500); nosound;
  1080.         chatr:=i; chatcall:=true;
  1081.       end else chatr:='';
  1082.     end else
  1083.       begin chatcall:=false; print('Chat call turned off.'); chatr:='';end;
  1084.   end;
  1085.   nl;nl; topscr;
  1086. end;
  1087.  
  1088. procedure yourinfo;
  1089. begin
  1090.   nl; nl;
  1091.   print('Your name : '+nam);
  1092.   print('Your SL   : '+cstr(thisuser.sl));
  1093.   print('Your DSL  : '+cstr(thisuser.dsl));
  1094.   print('You D/L''d : '+cstr(thisuser.dk)+'K in '+cstr(thisuser.downloads)+' files');
  1095.   print('You U/L''d : '+cstr(thisuser.uk)+'K in '+cstr(thisuser.uploads)+' files');
  1096. end;
  1097.  
  1098. procedure ftmainmenu;
  1099. var ii,i:str; int,inte:integer; rl:real;
  1100. begin
  1101.   dump; tleft; nl; nl;
  1102.   rl:=(seclev[thisuser.sl].ttime*60.0+extratime+timeon-timer);
  1103.   if rl>32767.0 then rl:=32000; if rl<0.0 then rl:=0;
  1104.   inte:=trunc(rl);
  1105.   i:=cstr(inte div 3600)+':'; ii:=cstr((inte mod 3600) div 60);
  1106.   if length(ii)=1 then ii:='0'+ii; i:='T - '+i+ii+':';
  1107.   ii:=cstr(inte mod 60); if length(ii)=1 then ii:='0'+ii;
  1108.   i:=i+ii; print(i);
  1109.   i:='('+cstr(culb)+')-('+uboards[culb].name+')  :';
  1110.   prompt(i);
  1111.   helpl:='T';
  1112.   mmkey(i);
  1113.   helpl:=#0;
  1114.   if length(i)=1 then case i[1] of
  1115.     '?':printfile('gfiles\dlmenu.msg');
  1116.     'Q':doneft:=true;
  1117.     'B':browsefiles;
  1118.     'U':iul;
  1119.     'D':idl;
  1120.     'L':listfiles;
  1121.     'S':search;
  1122.     'F':searchd;
  1123.     'C':reqchat;
  1124.     'O':begin
  1125.           nl;nl;prompt('Hangup?  Sure? '); helpl:='O';
  1126.           if yn then begin
  1127.             cls;
  1128.             printfile('gfiles\logoff.msg');
  1129.             hangup:=true;
  1130.             hungup:=false;
  1131.           end;
  1132.         end;
  1133.     '*':listboards;
  1134.     'P':pointdate;
  1135.     'N':nf;
  1136.     'R':remove;
  1137.     'M':if cs then move;
  1138.     'V':lfii;
  1139.     'Y':yourinfo;
  1140.   end;
  1141.   if i='/O' then hangup:=true;
  1142.   if (i='SORT') and cs then sort;
  1143.   if (i='REN') and cs then ren;
  1144.   if (i='0') and cs then culb:=0;
  1145.   int:=value(i); if (int>0) and (int<=maxulb) then
  1146.     if thisuser.dsl>=uboards[int].dsl then
  1147.       if (uboards[int].password='') or cs then culb:=int else begin
  1148.         prompt('Password? '); input(i,10);
  1149.         if i<>uboards[int].password then
  1150.           print('Wrong.')
  1151.         else
  1152.           culb:=int;
  1153.        end;
  1154. end;
  1155.  
  1156. begin
  1157.   iport; i1; doneft:=false;
  1158.   while (not doneft) and (not hangup) do
  1159.     ftmainmenu;
  1160.   ret:=200;
  1161.   return;
  1162. end.